package com.example.redisdemo.netty.init;

import com.example.redisdemo.netty.handler.ChatHandler;
import com.example.redisdemo.netty.handler.HeartBeatServerHandler;
import com.example.redisdemo.util.SSLContextUtil;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import java.util.concurrent.TimeUnit;

/**
 * @author hexinglin
 * 初始化配置器
 * @created 2022-05-26 13:57
 **/
public class WsServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline pipeline = socketChannel.pipeline();

        //根据工具类将生成的jks证书解析进来
        SSLContext sslContext =
                SSLContextUtil.createSSLContext("JKS","D:\\Idea\\demo-oauth2-master\\redis-demo\\Redis篇\\src\\main\\resources\\webrtc.keystore","142939");
        //SSLEngine 此类允许使用ssl安全套接层协议进行安全通信
        SSLEngine engine = sslContext.createSSLEngine();
        engine.setUseClientMode(false);

        pipeline.addLast(new SslHandler(engine));

        /*
         * 说明
         * 1.IdleStateHandler 是Netty提供的处理空闲状态的处理器
         * 2.long readerIdleTime：表示多长时间没有读，就会发送一个心跳检测包检查是否连接
         * 3.long writerIdleTime：表示多长时间没有写，就会发送一个心跳检测包检查是否连接
         * 4.long allIdleTime：表示多长时间没有读写，就会发送一个心跳检测包检查是否连接
         * 5.文档说明
         * Triggers an IdleStateEvent when a Channel has not performed read, write, or both operation for a while.
         * 当通过在一段时间内没有发生读，写或者读写操作时，会触发一个IdleStateEvent（空闲事件）
         * 6. 当IdleStateEvent触发后，就会传递给管道的下一个Handler去处理，通过触发下一个handler的userEventTriggered时间，在
         * 该方法处理IdleStateEvent（读空闲，写空闲，读写空闲）
         */
        pipeline.addLast(new IdleStateHandler(15,15,30, TimeUnit.MINUTES));

        //websocket基于http协议，所以需要http编解码器
        pipeline.addLast(new HttpServerCodec());
        //添加对于读写大数据流的支持
        pipeline.addLast(new ChunkedWriteHandler());
        //对httpMessage进行聚合
        pipeline.addLast(new HttpObjectAggregator(1024 * 64));
        // ================= 上述是用于支持http协议的 ==============
        //websocket 服务器处理的协议，用于给指定的客户端进行连接访问的路由地址
        //比如处理一些握手动作(ping,pong)
        pipeline.addLast(new WebSocketServerProtocolHandler("/webrtc"));
        //自定义聊天handler
        pipeline.addLast(new ChatHandler());
        //自定义心跳handler
        pipeline.addLast(new HeartBeatServerHandler());

    }
}
